Skip to content

[EXPERIMENT] Replace ResumeTy with an unsafe binder ty.#146562

Draft
cjgillot wants to merge 6 commits intorust-lang:mainfrom
cjgillot:resume-ty
Draft

[EXPERIMENT] Replace ResumeTy with an unsafe binder ty.#146562
cjgillot wants to merge 6 commits intorust-lang:mainfrom
cjgillot:resume-ty

Conversation

@cjgillot
Copy link
Copy Markdown
Contributor

@cjgillot cjgillot commented Sep 14, 2025

View all comments

This actually is one of use cases unsafe binder types are meant to address. This PR tries to use them as so.

The implementation of unsafe binders is still incomplete, so this PR is mostly for experimentation and not meant to be merged.

r? @compiler-errors

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Sep 14, 2025

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 14, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Sep 14, 2025

compiler-errors is not on the review rotation at the moment.
They may take a while to respond.

@rust-log-analyzer

This comment has been minimized.

@compiler-errors
Copy link
Copy Markdown
Contributor

Maybe let's crater this?

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot added a commit that referenced this pull request Sep 15, 2025
[EXPERIMENT] Replace ResumeTy with an unsafe binder ty.
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Sep 15, 2025

💥 Test timed out after 21600s

@oli-obk
Copy link
Copy Markdown
Contributor

oli-obk commented Sep 15, 2025

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot added a commit that referenced this pull request Sep 15, 2025
[EXPERIMENT] Replace ResumeTy with an unsafe binder ty.
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Sep 15, 2025

☀️ Try build successful (CI)
Build commit: 342ed2e (342ed2e8608ee307743c341962b427652cdb06e9, parent: d1ed52b1f5b78bf66127b670af813b84d57aeedb)

@oli-obk
Copy link
Copy Markdown
Contributor

oli-obk commented Sep 15, 2025

@craterbot check

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-146562 created and queued.
🤖 Automatically detected try build 342ed2e
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 15, 2025
@craterbot
Copy link
Copy Markdown
Collaborator

🚧 Experiment pr-146562 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Copy Markdown
Collaborator

🎉 Experiment pr-146562 is completed!
📊 2 regressed and 7 fixed (699587 total)
📊 1491 spurious results on the retry-regessed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-146562/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Sep 17, 2025
@bors
Copy link
Copy Markdown
Collaborator

bors commented Sep 17, 2025

☔ The latest upstream changes (presumably #146666) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
Copy link
Copy Markdown
Contributor Author

@craterbot
Copy link
Copy Markdown
Collaborator

👌 Experiment pr-146562-1 created and queued.
🤖 Automatically detected try build 342ed2e
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 20, 2025
@craterbot
Copy link
Copy Markdown
Collaborator

🚧 Experiment pr-146562-1 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Copy Markdown
Collaborator

🎉 Experiment pr-146562-1 is completed!
📊 0 regressed and 0 fixed (1471 total)
📊 108 spurious results on the retry-regessed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-146562-1/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Sep 21, 2025
@cjgillot cjgillot marked this pull request as draft October 16, 2025 16:44
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 16, 2025
@cjgillot cjgillot force-pushed the resume-ty branch 2 times, most recently from f714d7b to 1420629 Compare May 8, 2026 21:58
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@oli-obk oli-obk assigned oli-obk and unassigned compiler-errors May 9, 2026
@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
##[endgroup]
Executing "/scripts/stage_2_test_set1.sh"
+ /scripts/stage_2_test_set1.sh
+ '[' 1 == 1 ']'
+ echo 'PR_CI_JOB set; skipping tidy'
+ SKIP_TIDY='--skip tidy'
+ ../x.py --stage 2 test --skip tidy --skip compiler --skip src
PR_CI_JOB set; skipping tidy
##[group]Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.04s
##[endgroup]
---
---- [ui] tests/ui/rustc_public-ir-print/async-closure.rs stdout ----
Saved the actual stdout to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/rustc_public-ir-print/async-closure/async-closure.stdout`
diff of stdout:

40     let  _3: i32;
41     let mut _4: &i32;
42     let mut _5: ();
-     let mut _6: unsafe<'a, 'b> &'a mut Context<'b>;
-     let mut _7: u32;
-     let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
-     debug _task_context => _6;
-     debug y => (*((*_8).0: &i32));
+     let mut _6: u32;
+     let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+     let mut _8: unsafe<'a, 'b> &'a mut Context<'b>;
+     debug _task_context => _8;
+     debug y => (*((*_7).0: &i32));
48     debug y => _3;
49     bb0: {
-         _8 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
-         _7 = discriminant((*_8));
-         switchInt(move _7) -> [0: bb1, 1: bb2, otherwise: bb3];
+         _8 = wrap_binder!(Move(_2); Ty { id: 12, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
+         _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
+         _6 = discriminant((*_7));
+         switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3];
53     }
54     bb1: {
-         _6 = wrap_binder!(Move(_2); Ty { id: 13, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
56         StorageLive(_3);
-         _4 = no_retag ((*_8).0: &i32);
+         _4 = no_retag ((*_7).0: &i32);
58         _3 = (*_4);
59         _5 = ();
60         StorageDead(_3);

61         _0 = Poll::Ready(move _5);
-         discriminant((*_8)) = 1;
+         discriminant((*_7)) = 1;
63         return;
64     }
65     bb2: {

74     let  _3: i32;
75     let mut _4: &i32;
76     let mut _5: ();
-     let mut _6: unsafe<'a, 'b> &'a mut Context<'b>;
-     let mut _7: u32;
-     let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
-     debug _task_context => _6;
-     debug y => (*((*_8).0: &i32));
+     let mut _6: u32;
+     let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+     let mut _8: unsafe<'a, 'b> &'a mut Context<'b>;
+     debug _task_context => _8;
+     debug y => (*((*_7).0: &i32));
82     debug y => _3;
83     bb0: {
-         _8 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
-         _7 = discriminant((*_8));
-         switchInt(move _7) -> [0: bb1, 1: bb2, otherwise: bb3];
+         _8 = wrap_binder!(Move(_2); Ty { id: 12, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
+         _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
+         _6 = discriminant((*_7));
+         switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3];
87     }
88     bb1: {
-         _6 = wrap_binder!(Move(_2); Ty { id: 13, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
90         StorageLive(_3);
-         _4 = no_retag ((*_8).0: &i32);
+         _4 = no_retag ((*_7).0: &i32);
92         _3 = (*_4);
93         _5 = ();
94         StorageDead(_3);

95         _0 = Poll::Ready(move _5);
-         discriminant((*_8)) = 1;
+         discriminant((*_7)) = 1;
97         return;
98     }
99     bb2: {

Note: some mismatched output was normalized before being compared
-     let mut _7: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6};
-         _7 = (_1.0: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6});
-     let mut _7: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6};
-         _7 = (_1.0: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6});
+     let mut _6: u32;
+     let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+     let mut _8: unsafe<'a, 'b> &'a mut Context<'b>;
+     debug _task_context => _8;
+     debug y => (*((*_7).0: &i32));
+         _8 = wrap_binder!(Move(_2); Ty { id: 12, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
+         _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
+         _6 = discriminant((*_7));
+         switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3];
+         _4 = no_retag ((*_7).0: &i32);
+         discriminant((*_7)) = 1;
+     let mut _6: u32;
+     let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
+     let mut _8: unsafe<'a, 'b> &'a mut Context<'b>;
+     debug _task_context => _8;
+     debug y => (*((*_7).0: &i32));
+         _8 = wrap_binder!(Move(_2); Ty { id: 12, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
+         _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6});
+         _6 = discriminant((*_7));
+         switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3];
+         _4 = no_retag ((*_7).0: &i32);
+         discriminant((*_7)) = 1;


The actual stdout differed from the expected stdout
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args rustc_public-ir-print/async-closure.rs`

error: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/rustc_public-ir-print/async-closure.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/rustc_public-ir-print/async-closure" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2024" "-Z" "unpretty=stable-mir" "--crate-type" "lib" "-C" "panic=abort" "-Zmir-opt-level=0"
--- stdout -------------------------------
// WARNING: This is highly experimental output it's intended for rustc_public developers only.
// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir.
fn foo() -> () {
    let mut _0: ();
    let  _1: i32;
    let  _2: {async closure@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:13: 9:21};
    let mut _3: &i32;
    debug y => _1;
    debug x => _2;
    bb0: {
        StorageLive(_1);
        _1 = 0_i32;
        StorageLive(_2);
        StorageLive(_3);
        _3 = &_1;
        _2 = {coroutine-closure@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:13: 9:21}(move _3);
        StorageDead(_3);
        _0 = ();
        StorageDead(_2);
        StorageDead(_1);
        return;
    }
}
fn foo::{closure#0}(_1: &{async closure@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:13: 9:21}) -> {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6} {
    let mut _0: {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6};
    let mut _2: &i32;
    let mut _3: &i32;
    debug y => (*((*_1).0: &i32));
    bb0: {
        StorageLive(_2);
        _3 = no_retag ((*_1).0: &i32);
        _2 = &(*_3);
        _0 = {coroutine@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6}(move _2);
        StorageDead(_2);
        return;
    }
}
fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
    let mut _0: Poll<()>;
    let  _3: i32;
    let mut _4: &i32;
    let mut _5: ();
    let mut _6: u32;
    let mut _7: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6};
    let mut _8: unsafe<'a, 'b> &'a mut Context<'b>;
    debug _task_context => _8;
    debug y => (*((*_7).0: &i32));
    debug y => _3;
    bb0: {
        _8 = wrap_binder!(Move(_2); Ty { id: 12, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
        _7 = (_1.0: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6});
        _6 = discriminant((*_7));
        switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3];
    }
    bb1: {
        StorageLive(_3);
        _4 = no_retag ((*_7).0: &i32);
        _3 = (*_4);
        _5 = ();
        StorageDead(_3);
        _0 = Poll::Ready(move _5);
        discriminant((*_7)) = 1;
        return;
    }
    bb2: {
        assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable];
    }
    bb3: {
        unreachable;
    }
}
fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
    let mut _0: Poll<()>;
    let  _3: i32;
    let mut _4: &i32;
    let mut _5: ();
    let mut _6: u32;
    let mut _7: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6};
    let mut _8: unsafe<'a, 'b> &'a mut Context<'b>;
    debug _task_context => _8;
    debug y => (*((*_7).0: &i32));
    debug y => _3;
    bb0: {
        _8 = wrap_binder!(Move(_2); Ty { id: 12, kind: RigidTy(UnsafeBinder(Binder { value: Ty { id: 19, kind: RigidTy(Ref(Region { kind: ReBound(0, BoundRegion { var: 0, kind: BrAnon }) }, Ty { id: 20, kind: RigidTy(Adt(AdtDef(DefId { id: 5, name: "std::task::Context" }), GenericArgs([Lifetime(Region { kind: ReBound(0, BoundRegion { var: 1, kind: BrAnon }) })]))) }, Mut)) }, bound_vars: [Region(BrAnon), Region(BrAnon)] })) });
        _7 = (_1.0: &mut {async closure body@/checkout/tests/ui/rustc_public-ir-print/async-closure.rs:9:22: 11:6});
        _6 = discriminant((*_7));
        switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3];
    }
    bb1: {
        StorageLive(_3);
        _4 = no_retag ((*_7).0: &i32);
        _3 = (*_4);
        _5 = ();
        StorageDead(_3);
        _0 = Poll::Ready(move _5);
        discriminant((*_7)) = 1;
        return;
    }
    bb2: {
        assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable];
    }
    bb3: {
        unreachable;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants